using System;
using System.Reflection;
using EnvDTE;
using EnvDTE80;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.VisualStudio.TeamFoundation.VersionControl;
using TeamReview.UI;

namespace TeamReview.Command
{
    /// <summary>
    /// Shows the <see cref="CodeReviewReplayWindow"/> in a docked position at the bottom of the editor pane of the IDE
    /// </summary>
    /// <remarks>
    /// <para>
    /// Makes the window visible again in cases when the <see cref="CodeReviewReplayWindow"/> 
    /// has already been created, and hidden or potentially moved
    /// </para>
    /// <para>
    /// Template Pattern implementor of <see cref="ShowFormCommand"/>
    /// </para>
    /// </remarks>
	public class ShowReplayWindowCommand : ShowFormCommand
	{
		private Window2 toolWindow;
        private readonly object lockObj = new object();
        private CodeReviewReplayWindow replayWindow;
        private readonly AddIn addIn;             
        private const string GuidString = "{9FFC9D9B-1F39-4763-A2AF-66AED06C799E}";

        private Window2 frame;

        public ShowReplayWindowCommand(DTE2 visualStudio, AddIn teamAddin) : base(visualStudio)
        {
            addIn = teamAddin;
        }

        /// <summary>
        /// Activate <see cref="CodeReviewReplayWindow"/>, set it's caption and make it visible.
        /// </summary>
		protected override void ShowForm()
		{
            if (toolWindow == null)
            {
                toolWindow = ActivateToolWindow();
            }
            toolWindow.Caption = "Code Review Replay";
			toolWindow.Visible = true;
		}

        //private string GetProjectName()
        //{
        //    VersionControlExt versionControl = shellDTE.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as VersionControlExt;
        //    if ((versionControl == null) || (versionControl.SolutionWorkspace==null))
        //        return string.Empty;

        //    TeamProject teamProject = versionControl.SolutionWorkspace.GetTeamProjectForLocalPath(shellDTE.DTE.Solution.FullName);
        //    return teamProject.Name;
        //}

        /// <summary>
        /// Add an instance of <see cref="CodeReviewReplayWindow"/>
        /// to the <see cref="DTE2.Windows"/>, dock it at the bottom of the 
        /// editor pane of the IDE, and activate it within a new frame
        /// </summary>
        /// <returns></returns>
        private Window2 ActivateToolWindow()
        {
            lock (lockObj)
            {             
                object programmableObject = null;

                Assembly asm = Assembly.GetExecutingAssembly();

                Windows2 windows2 = (Windows2)shellDTE.Windows;
                toolWindow = (Window2)windows2.CreateToolWindow2(addIn, asm.Location,
                                      "TeamReview.UI.CodeReviewReplayWindow", "Code Review Replay", GuidString, ref programmableObject);


                Window2 outputWindow = (Window2)shellDTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
                outputWindow.Visible = false;


                CodeReviewReplayWindow replayWindow = programmableObject as CodeReviewReplayWindow;
                if (replayWindow != null)
                {
                  replayWindow.Shell = shellDTE;  
                }

                frame = (Window2)shellDTE.Windows.CreateLinkedWindowFrame(outputWindow, toolWindow, vsLinkedWindowType.vsLinkedWindowTypeDocked);
                frame.SetKind(vsWindowType.vsWindowTypeLinkedWindowFrame);
                frame.Height = 200;
                shellDTE.MainWindow.LinkedWindows.Add(frame);
                frame.Activate();
              

            }
            return toolWindow;
        }



        private void CloseToolWindow()
        {
            if (toolWindow == null)
                return;
            
            toolWindow.Detach();
            toolWindow.Close(vsSaveChanges.vsSaveChangesNo);
            toolWindow = null;

            if (frame != null)
            {
                shellDTE.MainWindow.LinkedWindows.Remove(frame);
            }
            frame = null;
        }

        public override void Shutdown()
        {
            try
            {
                CloseToolWindow();
            }
            catch (Exception e)
            {
                Instrumentation.Log(e);
            }
        }
	}
}